package com.ocom.payconfig.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.ocom.common.dto.GetMealTimeDto;
import com.ocom.common.entity.card.EntityXfChannelInfo;
import com.ocom.common.entity.card.EntityXfMealInfo;
import com.ocom.common.entity.company.EntityCompanyConfig;
import com.ocom.common.entity.payconfig.EntityForecastData;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.payconfig.*;
import com.ocom.common.request.payconfig.mealorder.GetOrderPlanDishesRequest;
import com.ocom.common.request.payconfig.mealorder.GetOrderPlanDishesResponse;
import com.ocom.common.request.payhandle.OrderDishesPayRequest;
import com.ocom.common.request.ugcapi.OrderMealPlanSubmitRequest;
import com.ocom.common.request.web.ConsTimeConfigOnShowRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.NumConvertUtil;
import com.ocom.common.utils.RandomUtil;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.pay.CheckVo;
import com.ocom.common.vo.payconfig.PersonAndDeptVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.controller.MealOrderController;
import com.ocom.payconfig.dao.IDaoForecastData;
import com.ocom.payconfig.dao.IDaoPersonnelInfo;
import com.ocom.payconfig.dao.IDaoXfMealTime;
import com.ocom.payconfig.service.ForecastDataService;
import com.ocom.payconfig.service.XfMealInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;

@Slf4j
@Service
public class ForecastDataServiceImpl extends ServiceImpl<IDaoForecastData, EntityForecastData> implements ForecastDataService {
    @Autowired
    private IDaoPersonnelInfo daoPersonnelInfo;

    @Autowired
    private IDaoXfMealTime daoXfMealTime;

    @Autowired
    private IDaoForecastData daoForecastData;

    @Autowired
    private XfMealInfoService xfMealInfoService;

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "comId", isMaster = MasterSlaveEnum.SLAVE)
    public Result updateOrderForecastDetail(Long companyId, UpdateOrderForecastDetailRequest request) {
        request.setMealDate(DateUtil.beginOfDay(request.getMealDate()));


        if(request.getNumber() > 0){
            Date now = new Date();
            Date dateA = DateUtil.offset(DateUtil.offset(request.getMealDate(), DateField.DAY_OF_MONTH,request.getAllowDays()), DateField.HOUR,request.getAllowTime());
            if(!(request.getMealDate().after(DateUtil.beginOfDay(now)) && dateA.after(now))){
                return ResultUtil.success();
            }

        }
        QueryWrapper<?> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(" p.com_id",request.getComId()).eq(" p.status",0).eq("p.p_code",request.getPCode()).eq("p.p_name",request.getPName()).orderByDesc("p.p_id").last("limit 1");

        PersonAndDeptVo personAndDept = daoPersonnelInfo.selectPerson(queryWrapper);
        if(ObjectUtil.isEmpty(personAndDept)){
            return ResultUtil.error(ResultEnum.Err_303);
        }

        List<EntityForecastData>  forecastDataList = this.list(Wrappers.lambdaQuery(EntityForecastData.class)
                .eq(EntityForecastData::getComId,request.getComId())
                .eq(EntityForecastData::getPId,personAndDept.getPId())
                .eq(EntityForecastData::getMealDate,request.getMealDate())
                .eq(EntityForecastData::getMealNo,request.getMealNo())
        );
        if(ObjectUtil.isNotEmpty(forecastDataList)){
            for(EntityForecastData entityForecastData: forecastDataList){
                if(!entityForecastData.getStatus().equals(2)){
                    if(request.getNumber() == 0){
                        request.setMealDate(null);
                        request.setAllowTime(null);
                        request.setAllowDays(null);
                    }
                    entityForecastData.setPointId(request.getPointId());
                    entityForecastData.setNumber(request.getNumber());
                    entityForecastData.setAllowDays(request.getAllowDays());
                    entityForecastData.setAllowTime(request.getAllowTime());
                    entityForecastData.setOverdraw(request.getOverdraw());
                    entityForecastData.setStatus(request.getNumber() == 0?4:1);
                    this.updateById(entityForecastData);
                }
            }
        }else{
            if(!request.getNumber().equals(0)){
                EntityForecastData entityForecastData = new EntityForecastData();
                entityForecastData.setMealDate(request.getMealDate());
                entityForecastData.setComId(request.getComId());
                entityForecastData.setPointId(request.getPointId());
                entityForecastData.setNumber(request.getNumber());
                entityForecastData.setAllowDays(request.getAllowDays());
                entityForecastData.setAllowTime(request.getAllowTime());
                entityForecastData.setOverdraw(request.getOverdraw());
                entityForecastData.setStatus(1);
                entityForecastData.setMealNo(request.getMealNo());
                entityForecastData.setPId(personAndDept.getPId());
                entityForecastData.setCreateTime(new Date());
                this.save(entityForecastData);
            }

        }
        return ResultUtil.success();
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "companyId", isMaster = MasterSlaveEnum.SLAVE)
    public Result getOrderForecastMealNo(Long companyId, GetOrderForecastMealNoRequest request) {
        QueryWrapper<?> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("i.com_id",request.getComId())
                .eq("t.point_id",request.getPointId())
                .lt("t.advance_money",0)
                .groupBy("i.meal_no")
                .orderByDesc("i.meal_no");
        return ResultUtil.success(this.daoXfMealTime.getOrderForecastMealNo(queryWrapper));
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, companyId = "companyId", isMaster = MasterSlaveEnum.SLAVE)
    public Result getOrderForecastDetail(Long companyId, GetOrderForecastDetailRequest request) {
        if(ObjectUtil.isEmpty(request.getStartDate())){
            request.setStartDate(DateUtil.beginOfDay(new Date()));
        }
        if(ObjectUtil.isEmpty(request.getEndDate())){
            request.setEndDate(DateUtil.endOfDay(new Date()));
        }

        List<EntityXfMealInfo> mealNoVoList = this.xfMealInfoService.list(Wrappers.lambdaQuery(EntityXfMealInfo.class).eq(EntityXfMealInfo::getComId,request.getComId()).groupBy(EntityXfMealInfo::getMealNo).orderByDesc(EntityXfMealInfo::getMealNo));
        if(ObjectUtil.isEmpty(mealNoVoList)){
            return ResultUtil.success();
        }
        QueryWrapper<?> queryWrapper1 = new QueryWrapper<>();
        QueryWrapper<?> queryWrapper2 = new QueryWrapper<>();
        List<String> field1 = Lists.newArrayList("f.p_id as pId","d.dept_id AS deptId","d.dept_name AS deptName","p_name AS pName","p_code AS pCode","meal_date AS mealDate","f.status","DATE_FORMAT(DATE_ADD(meal_date,INTERVAL (- allow_days *24 +allow_time) HOUR ), '%Y-%m-%d %H:%i:%s') AS consTime");
        List<String> field2 = Lists.newArrayList("fd.`status`");
        for (int i = 0; i < mealNoVoList.size(); i++) {
            String f1 = "sum(case when meal_no= \""+mealNoVoList.get(i).getMealNo()+"\" then number  else 0 end) mealNo"+mealNoVoList.get(i).getMealNo();
            String f2 = "sum(case when fd.`meal_no`= \""+mealNoVoList.get(i).getMealNo()+"\" then number  else 0 end) mealNo"+mealNoVoList.get(i).getMealNo();
            field1.add(f1);
            field2.add(f2);
        }

        queryWrapper1.select(StrUtil.join(",",field1));
        queryWrapper2.select(StrUtil.join(",",field2));
        queryWrapper1.eq("f.com_id",request.getComId()).between("f.meal_date",request.getStartDate(),request.getEndDate());
        queryWrapper2.eq("fd.com_id",request.getComId()).between("fd.meal_date",request.getStartDate(),request.getEndDate());

        List<String> deptIds = Arrays.asList(StrUtil.split(request.getDeptIds(),","));
        if(ObjectUtil.isNotEmpty(deptIds)){
            queryWrapper1.in("p.dept_id",deptIds);
            queryWrapper2.in("p.dept_id",deptIds);
        }

        if(ObjectUtil.isNotEmpty(request.getPCode())){
            queryWrapper1.eq("p_code",request.getPCode());
            queryWrapper2.eq("p_code",request.getPCode());
        }
        if(ObjectUtil.isNotEmpty(request.getPName())){
            queryWrapper1.like("p_name",request.getPName());
            queryWrapper2.like("p_name",request.getPName());
        }
        if(ObjectUtil.isNotEmpty(request.getStatus())){
            queryWrapper1.eq("f.status",request.getStatus());
            queryWrapper2.eq("fd.status",request.getStatus());
        }

        if(ObjectUtil.isNotEmpty(request.getPointId())){
            queryWrapper1.eq("f.point_id",request.getPointId());
            queryWrapper2.eq("fd.point_id",request.getPointId());
        }
        queryWrapper1.groupBy("f.com_id","f.p_id","f.meal_date");
        Page<?> page = new Page<>();
        page.setCurrent(request.getPage());
        page.setSize(request.getSize());
        IPage<Map<String,Object>> personForecastDataVoIPage = this.daoForecastData.getForecastData(page,queryWrapper1);

        List<Map<String,Object>> summary = new ArrayList<>();
        if(request.getSelSum() == 1){
//            if(ObjectUtil.isNotEmpty(request.getStatus())){
//                queryWrapper2.eq("fd.status",request.getStatus());
//            }
             summary = this.daoForecastData.summary(queryWrapper2);
        }


        Map<String,Object> map = new HashMap<>();
        map.put("total",personForecastDataVoIPage.getTotal() == -1? personForecastDataVoIPage.getRecords().size():personForecastDataVoIPage.getTotal());
        map.put("meal",mealNoVoList);
        map.put("list",personForecastDataVoIPage.getRecords());
        map.put("selSum",ObjectUtil.isEmpty(summary)?new ArrayList<>():summary);
        return ResultUtil.success(map);
    }

}
